const multiparty = require('multiparty')
const fs = require('fs')
const path = require('path')
const gm = require('gm').subClass({ iamgeMagick: true })

/**
 * @method 保证路径存在
 * @param {string} dirpath - 需要创建的路径
 * @param {function} cb - 回调函数
 */
const mkdirs = (dirpath, cb) => {
	fs.access(dirpath, fs.constants.F_OK, err => {
		if(err) {
			if (err.code === 'EEXIST') {// 存在
				cb();
			} else if(err.code === 'ENOENT') {// 不存在就递归创建
				mkdirs(path.dirname(dirpath), () => fs.mkdir(dirpath, cb));
			}
		} else {
			cb();
		}
	});
}

/**
 * @method 对象属性中数组只有一个元素的，则提取出来替换该数组
 * @description 不支持传字符串, 仅限[object Object]、[object Array]，其他类型直接返回
 * @param {[object Object] or [object Array]} result - 需要处理的json对象
 * @returns {object}
 */
const formatJson = result => {
	let message = void 0;

	// if(!(Object.prototype.toString.call(result) === '[object object]'
	// 	|| Object.prototype.toString.call(result) === '[object Array]')) {
	// 		throw new Error('仅限[object Object]和[object Array]');
	// }

	try { result = JSON.parse(JSON.stringify(result)); }
	catch(err) { throw new Error(err) }

	if(Array.isArray(result)) {// array
		if(result.length === 1) {
			if(Object.prototype.toString.call(result[0]) !== '[object Object]' &&
				!Array.isArray(result[0])) {// 非object，非array
				message = result[0];
			} else {
				message = formatJson(result[0]);
			}
		} else {
			message = [];
			for(const val of result) {
				message.push(formatJson(val));
			}
		}
	} else if(Object.prototype.toString.call(result) === '[object Object]') {// object
		message = {};
		for(const key in result) {// 遍历键
			if(Object.prototype.toString.call(result[key]) !== '[object Object]' &&
				!Array.isArray(result[key])) {// 简单类型
				message[key] = result[key];
			} else {
				message[key] = formatJson(result[key]);
			}
		}
	} else {// 其它类型直接返回
		message = result;
	}
  return message;
}

/**
 * 转换异步函数为thunk函数
 * @method
 * @param {function} fn - 需要转换的函数
 */
const thunkifyCB = fn => function() {
	const args = Array.from(arguments);
	return cb => {
		args.push(cb);
		return fn.apply(this, args)
	}
}

/**
 * 
 * @method 自执行基于thunk的generator函数
 * @param {funcition} gen - generator函数
 */
const runThunkGen = gen => {
  const g = gen();
  function next(data) {
    const result = g.next(data);
    if(result.done) return;
    result.value(next);
  }
  next();
}

/**
 * @method 图片统一处理
 * @param {string} oldPath - 要优化的图片的路径
 * @param {string} rePath - 更换路径
 * @param {[object array]} size - 宽高尺寸
 * @param {function} cb - 回调
 */
const gmOper = (oldPath, rePath, size, cb) => {
	gm(path.resolve(oldPath))
	.resize(size[0], size[1])
	.crop(size[0], size[1], 0, 0)
	.autoOrient()
	.write(path.resolve(rePath), err => {
		if(err) {
			throw new Error(err);
		} else {
			cb();
		}
	});
}

/**
 * @method 封装Object.prototype.toString.call
 * @description 比如，'[object Number]' returns 'number'
 * @param {any} val
 * @returns {string}
 */
const getOPTC = content => {
	return Object.prototype.toString.call(content).replace(/^\[object |\]$/g, '').toLowerCase();
}

module.exports = {
  mkdirs, formatJson, thunkifyCB, runThunkGen, gmOper, getOPTC
}